package com.example.player.util;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.media.MediaScannerConnection;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;

import com.example.player.domain.entity.Song;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cn.hutool.core.util.StrUtil;

/**
 * 本类为处理安卓音乐相关问题的工具类
 * @author 朱文权
 * */
public class MusicUtil {
    /**
     * 快速扫描音乐文件
     * 服务于后续方法
     * */
    private static List<Song> scanMusicFiles(Context context){
        //定义音乐数组
        List<Song> songs=new ArrayList<>();
        Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
                , null, null, null, MediaStore.Audio.AudioColumns.IS_MUSIC);
        String selection=null;
        //获取音频数据
        try{
            if(cursor!=null){
                while(cursor.moveToNext()){
                    //获取一条条音乐数据并且放入数组中
                    Song song=new Song();
                    song.setDuration(processMilli(cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))));
                    song.setTitle(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)));
                    song.setArtist(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)));
                    song.setPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));
                    Long size=cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
                    Log.d("TAG","转换前："+size);
                    song.setSize(processSize(BigDecimal.valueOf(size).doubleValue()));
                    String displayName=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
                    song.setType(StrUtil.subAfter(displayName,".",true));
                    songs.add(song);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            Log.e("ERROR","获取音乐文件出错："+e.getMessage());
        }
        return songs;
    }
    /**
     * 过滤数据库已有音乐文件
     * 向页面返回新增数据
     * */
    public static List<Song> getNewSongs(Context context,Set<Song> storedSongs){
        //新添的数据
        List<Song> newSongs=new ArrayList<>();
        //调用方法获取扫描的音乐文件
        List<Song> scanMusicFiles = scanMusicFiles(context);
        //对扫描的音乐文件进行遍历
        for(Song song:scanMusicFiles){
            if(!storedSongs.contains(song)&&examSong(song)){
                //缓存封面
                song.setCoverPath(cacheAlbumArtToAudioDir(context,song,song.getTitle()+System.currentTimeMillis()+".cover"));
                newSongs.add(song);
            }
        }
        //返回新添的数据
        return newSongs;
    }
    /**
     * 处理字节大小B
     * */
    private static String processSize(Double size){
        int cnt=0;
        while(size>1024){
            size/=1024;
            cnt++;
        }
        String sizeStr=size.toString();
        sizeStr=StrUtil.sub(sizeStr,0,StrUtil.indexOf(sizeStr,'.')+3);
        switch (cnt){
            case 0:
                sizeStr+="B";
                break;
            case 1:
                sizeStr+="KB";
                break;
            case 2:
                sizeStr+="MB";
                break;
            default:
                sizeStr="大小超出GB";
        }
        return sizeStr;
    }
    /**
     * 处理毫秒
     * */
    private static String processMilli(Long milli){
        milli/=1000;
        if(milli>=3600){
            return "时长超出小时";
        }
        String second=":";
        String minute="";
        Long m=milli/60;
        if(m==0){
            minute="00";
        }
        else if(m<10){
            minute="0"+m;
        }
        else{
            minute+=m;
        }
        Long s=milli%60;
        if(s==0){
            second+="00";
        }
        else if(s<10){
            second+="0"+s;
        }
        else{
            second+=s;
        }
        return minute+second;
    }
    /**
     * 检验音乐有效性
     * */
    private static Boolean examSong(Song song){
        //看时长
        return !StrUtil.subBefore(song.getDuration(),":",true).equals("00");
    }
    /**
     *缓存封面
     * @return 封面缓存地址
     * */
    private static String cacheAlbumArtToAudioDir(Context context, Song song, String coverFileName) {
        String audioFilePath=song.getPath();
        //获取公共目录
        File parentDir = context.getExternalMediaDirs()[0];
        // 检查目录是否存在且可写
        if (parentDir == null || !parentDir.exists() || !parentDir.canWrite()) {
            Log.w("音频警告", "不能写入该目录 " +
                    (parentDir != null ? parentDir.getAbsolutePath() : "null"));
            return null;
        }
        // 3. 创建封面文件
        File coverFile = new File(parentDir, coverFileName + ".jpg");
        // 1. 获取音频文件封面Bitmap
        Bitmap albumArt = extractAlbumArt(audioFilePath);
        if (albumArt == null) {
            Log.d("网络加载","正在从网络加载"+song.getTitle());
            String coverPath=parentDir.getAbsolutePath()+"/"+song.getTitle()+System.currentTimeMillis()+".cover.jpg";
            if(Network.downloadCover(song.getTitle(),coverPath)){
                return coverPath;
            }
            Log.e("网络加载失败","加载失败"+song.getTitle());
            return null;
        }
        // 4. 保存封面到文件
        try (FileOutputStream out = new FileOutputStream(coverFile)) {
            albumArt.compress(Bitmap.CompressFormat.JPEG, 90, out);
            Log.d("音频信息", "封面保存至 " + coverFile.getAbsolutePath());
            return coverFile.getAbsolutePath();
        } catch (IOException e) {
            Log.e("音频错误", "缓存封面失败", e);
            // 删除可能创建的不完整文件
            if (coverFile.exists()) {
                coverFile.delete();
            }
            return null;
        }
    }
    /**
     * 从音频文件提取封面Bitmap
     */
    private static Bitmap extractAlbumArt(String audioFilePath) {
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            retriever.setDataSource(audioFilePath);
            byte[] art = retriever.getEmbeddedPicture();
            if (art != null) {
                return BitmapFactory.decodeByteArray(art, 0, art.length);
            }
        } catch (Exception e) {
            Log.e("音频错误", "提取封面失败", e);
        } finally {
            try {
                retriever.release();
            } catch (IOException e) {
                Log.e("音频错误", "释放失败", e);
            }
        }
        return null;
    }

}
